#include "lib.h"

#include <algorithm>

using namespace std;

/******************************************************************************
 *
 * Définition des fonctions
 *
 *****************************************************************************/
  
/** @addtogroup Utilitaires
 *  @{
 */

/** Effectue a^b.
 * Nécessaire pour élever un entier à une puissance entière, car la
 * STL définit power pour float et des double.
 *
 * @param a mantisse
 * @param b exposant
 * @return a^b
 */
int puissance(int a, unsigned int b)
{
  if (b > 0)
    return a * puissance (a, b-1);
  else
    return 1;      
}

/** Retourne le digit désiré d'un nombre.

 * On extrait donc le chiffre b d'un nombre a. On commence par faire
 * une division entière, puis on prend le modulo (pour avoir le digit
 * voulu).
 *
 * @code
 * return ( a / puissance(10, b ) ) % 10;
 * @endcode
 *
 * @param a le nombre.
 * @param b le digit.
 * @return le chiffre voulu.
 */
unsigned int digit(const int& a, const int& b)
{
  return ( a / puissance(10, b ) ) % 10;
  /* 
     unsigned int retour(0);
     retour = a / puissance(10, b);
     if (retour > 9)
     retour = retour % 10;
     return retour;
  */
}

/**
 * Demande à l'utilisateur d'entrer un nombre entier et vérifie que
 * la saisie est valide. Si la saisie est erronée, l'utilisateur est
 * demandé d'entrer un nombre valide.
 *
 * @param question demande quoi entrer.
 * @return le nombre entré.
 */
unsigned int demanderUnsigned(const string& question)
{
  Debug::empileNiveau();
  func() << "demanderUnsigned -> début" << endreq;
  bool encore(false);
  unsigned int retour;
  string poubelle;

  do
    {
      blank() << question;
      cin >> retour;
      Debug::Toggle(false);

      encore = cin.fail();

      if (encore)
	{
	  warning() << endreq << "Entrer un nombre entier!" << endreq;
	  cin.clear();
	  getline(cin, poubelle);
	}
    }
  while(encore);

  Debug::Toggle(false);

  func() << "demanderUnsigned -> fin" << endreq;
  Debug::depileNiveau();

  return retour;
}

/**
 * Demande à l'utilisateur d'entrer un nombre entier et vérifie que
 * la saisie est valide. Si la saisie est erronée, l'utilisateur est
 * demandé d'entrer un nombre valide. Ce nombre est en plus borné.
 *
 * On fait simplement appel à demanderUnsigned tant que le résultat
 * n'est pas dans l'intervalle désiré.
 *
 * @param question demande quoi entrer
 * @param min la borne inférieure
 * @param max la borne supérieure
 * @return le nombre entré
 */
unsigned int demanderUnsignedBorne(const string& question,
				     const unsigned int& min,
				     const unsigned int& max)
{
  Debug::empileNiveau();
  func() << "demanderUnsignedBorne -> début" << endreq;
  unsigned int nbr;
  bool encore(false);

  do
    {
      nbr = demanderUnsigned(question);

      encore = (nbr < min || nbr > max);

      if (encore)
	warning() << "Entrer un nombre entier entre " << min
		   << " et " << max << " !" << endreq;
    }
  while(encore);

  Debug::Toggle(false);

  func() << "demanderUnsignedBorne -> fin" << endreq;
  Debug::depileNiveau();

  return nbr;
}

/** Affiche les accents des sphères et écoles de magie.

 * Permet d'obtenir le nom des écoles de magie et sphères sous une
 * forme lisible, au lieu de la syntaxe LaTeX utilisée dans le
 * stockage.
 *
 * Gère les "é", "à" et "ô" uniquement pour l'instant, car les autres
 * lettres accentuées ne sont pas utilisées.
 *
 * \b Exemple : "Alt\\'eration" devient "Altération".
 *
 * Le niveau de sortie est paramétré par Debug::itsLevel :\n
 * \e FUNC affiche le message de début et fin d'exécution.\n
 * \e LFUNC permet d'afficher chaque étape.
 *
 * @param brut la string originale.
 * @return la string contenant des accents lisibles.
 */
string afficheAccent(const string& brut)
{
  Debug::empileNiveau();
  func() << "afficheAccent -> début" << endreq;
  
  string retour(brut);
  size_t loc(retour.find("\\'", 0));
  while (loc != string::npos)
    {
      lfunc() << retour << ' ' << loc << " -> " <<endreq;
      retour.replace(loc, 3, "é");
      loc = retour.find("\\'", 0);
      lfunc() << retour << endreq;
    }
  loc = retour.find("\\`", 0);
  while (loc != string::npos)
    {
      lfunc() << retour << ' ' << loc << endreq;
      retour.replace(loc, 3, "à");
      loc = retour.find("\\`", 0);
    }
  loc = retour.find("\\^", 0);
  while (loc != string::npos)
    {
      lfunc() << retour << ' ' << loc << endreq;
      retour.replace(loc, 3, "ô");
      loc = retour.find("\\^", 0);
    }
  func() << "afficheAccent -> fin" << endreq;
  Debug::depileNiveau();
  return retour;
}

/**
 * Vérifie si une valeur est déjà dans un vecteur. Sert lors du choix
 * d'une compétence, d'un sort, ...
 *
 * Si valeur est déjà présent dans le vecteur adressé par ptr, le
 * résultat sera true, et on saura qu'il ne faut pas ajoutter la
 * compétence, sort,...
 *
 * Le niveau de sortie est paramétré par Debug::itsLevel :\n
 * - \e FUNC affiche les messages de début et de fin de méthode.\n
 * - \e DEBUG affiche la position où l'élément a été trouvé.
 *
 * @param ptr pointeur sur le vecteur à vérifier.
 * @param valeur valeur à ajouter.
 * @return résultat du test.
 */
bool safePushBack(vector<unsigned int> *ptr, const unsigned int& valeur)
{
  Debug::empileNiveau();
  func() << "safePushBack -> début" << endreq;
  
  vector<unsigned int>::iterator loc, Begin(ptr -> begin()), End(ptr -> end());

  if (Begin == End)
    return false;

  loc = find(Begin, End, valeur);

  debug() << "Position : " << (int) (loc - Begin)
	  << " sur une taille de " << ptr -> size() << endreq;


  func() << "safePushBack -> fin" << endreq;
  Debug::depileNiveau();

  return !(loc == End);
}

/**
 * Vérifie si une valeur est déjà dans un vecteur. Sert lors du choix
 * d'une compétence, sans tenir compte des pourcentages associés à
 * certaines compétences.
 *
 * Si valeur est présent dans le vecteur adressé par ptr mais pas dans
 * sauter, alors le résultat sera \e true. Par contre, si valeur est
 * présent à la fois dans ptr et sauter, alors on n'en tient pas
 * compte et le résultat est \e false.
 *
 * Le niveau de sortie est paramétré par Debug::itsLevel :\n
 * - \e FUNC affiche les messages de début et de fin de méthode.\n
 * - \e DEBUG affiche l'élément à trouver et sa position.
 *
 * @param ptr pointeur sur le vecteur à vérifier.
 * @param valeur valeur à ajouter.
 * @param sauter vecteur des emplacements à ne pas vérifier.
 * @return résultat du test.
 */
bool safePushBack(vector<unsigned int> *ptr, const unsigned int& valeur,
		    vector<unsigned int>& sauter)
{
  Debug::empileNiveau();
  func() << "safePushBack -> début" << endreq;

  vector<unsigned int>::iterator loc, Begin(ptr -> begin()), End(ptr -> end()),
    sBegin(sauter.begin()), sEnd(sauter.end()), sIt, fBegin;
  bool retour(true);
  fBegin = Begin;

  if (Begin == End)
    return false;
  
  do
    {
      loc = find(fBegin, End, valeur);
      if (loc == End)
	{
	  retour = false;
	  break;
	}
      debug() << "A chercher : " << (unsigned int)(loc - Begin) << endreq;
      sIt = find(sBegin, sEnd, (unsigned int)(loc - Begin));
      if (sIt != sEnd)
	{
	  retour = false;
	  fBegin = ++loc;
	}
      else
	{
	  retour = true;
	  break;
	}
    }
  while(loc != End);
  
   debug() << "Position : " << (int) (loc - Begin)
 	  << " sur une taille de " << ptr -> size() << endreq;

  func() << "safePushBack -> fin" << endreq;
  Debug::depileNiveau();
  
  return retour;
}

/**
 * Retranscrit les arguments du programme principal pour gérer les noms
 * composés.
 *
 * Comme on sait que les arguments du programme principal sont Nom
 * Race Classe(s), on va concaténer les arguments qui ne sont pas des
 * nombres.
 *
 * Le niveau de sortie est paramétré par Debug::itsLevel :\n
 * - \e FUNC affiche les messages de début et de fin de méthode.\n
 * - \e DEBUG affiche la ligne d'argument originale, puis les
 * éventuelles fusions.
 *
 * @param tab arguments originaux.
 * @param nbr dimension du tableau.
 * @param retour conteneur des nouveaux arguments, modifié dans la
 * fonction.
 * @return nombre de nouveaux arguments.
 */
void gererEspacesBlancs(char* tab[], int& nbr,
			  vector<string>& retour)
{
  Debug::empileNiveau();
  func() << "gererEspacesBlancs -> début" << endreq;

  retour.clear();
  for (unsigned int i(0); i < static_cast<unsigned int>(nbr); i++)
    {
      retour.push_back(tab[i]);
      debug() << retour.back() << endreq;
    }

  debug() << endreq;

  vector<string>::iterator it, Begin(++retour.begin()), End(retour.end());

  for (it = ++Begin; it != retour.end(); it++)
    {
      if ((*it)[0] < 48 || (*it)[0] > 57)
	{
	  *(it - 1) += "\\ " + *it;
	  retour.erase(it);
	  debug() << "Fusion en " << *(it -1) << endreq;
	  it--;
	}
    }

  debug() << endreq;

  size_t loc(retour[1].find("\'"));
  if (loc != string::npos)
    retour[1].replace(loc, 1, "\\'");

  nbr = retour.size();

  func() << "gererEspacesBlancs -> fin" << endreq;
  Debug::depileNiveau();
}

/** Permet de lire un vecteur d'entiers non signés depuis une chaîne
 * de caractères.
 * On parcours alors la chaîne de catactères et on récupère les
 * sous-chaînes qui sont séparées par des espaces. On lit ensuite la
 * valeur en appelent lireString et on stocke le résultat dans le
 * conteneur de sortie si la lecture se fait sans erreur.
 *
 * Le niveau de sortie est paramétré par Debug::itsLevel :\n
 * - \e FUNC affiche les messages de début et de fin de méthode.\n
 * - \e LINFO affiche la chaîne de caractère originale et chaque valeur
 * individuelle à convertir.
 *
 *
 * @param donnees chaîne de caractères à "lire".
 * @param vec pointeur sur le conteneur dans lequel seront stockées
 * les valeurs.
 * @return \e true si tout s'est bien passé, \e false sinon, ce qui
 * signifie qu'une conversion en unsigned int s'est mal déroulée.
 */
bool lireVectorUInt(const string& donnees, vector< unsigned int> *vec)
{
  Debug::empileNiveau();
  func() << "lireVectorUInt -> début" << endreq;

  vec -> clear();

  size_t taille( donnees.size() ), i(0);

  linfo() << "Vecteur complet " << donnees << endreq;

  string tmp;

  unsigned int nbr;

  for (i = 0; i < taille; i++)
    {
      while  ( donnees[i] == ' ' && i < taille )
	i++;
      tmp = "";
      while ( donnees[i] != ' ' && i < taille )
	{
	  tmp += donnees[i];
	  i++;
	}

      linfo() << "Valeur à convertir : " << tmp << endreq;

      if ( ! lireString( tmp, nbr ) )
	{
	  error() << "Ne peut pas convertir " << tmp << endreq;
	  func() << "lireVectorUInt -> fin" << endreq;
	  Debug::depileNiveau();
	  return false;
	}
      vec -> push_back( nbr );
    }

  func() << "lireVectorUInt -> fin" << endreq;
  Debug::depileNiveau();
  return true;
}

/**
 * Permet de déterminer les ajustements aux talents de voleurs. Sert
 * bien évidemment à la création d'un Voleur, mais aussi d'un Barde et
 * pour les Mage et Clerc ayant des talent de voleur.
 *
 * @param race nom de la Race.
 * @param dext valeur du trait Dexterité.
 * @param ptr pointeur sur le conteneur des ajustement
 */
void determinerScoresAjustes(const string& race, const unsigned int& dext,
			     vector< int >*& ptr)
{
  Debug::empileNiveau();
  func() << "determinerScoresAjustes -> début" << endreq;

  ptr -> assign(13, 0);

  if (race == "Nain")
    {
      ptr -> operator[](0)  -= 5;   // corruption
      ptr -> operator[](1)  += 10;  // crochetage
      ptr -> operator[](4)  += 5;   // détection de la magie
      ptr -> operator[](5)  += 5;   // détection des illusions
      ptr -> operator[](7)  -= 10;  // escalade
      ptr -> operator[](8)  -= 5;   // lire des langues inconnues
      ptr -> operator[](9)  += 10;  // creuser des tunnels
      ptr -> operator[](11) += 15;  // trouver et désamorcer les pièges
    }
  else if (race == "Elfe")
    {
      ptr -> operator[](0)  += 15;  // corruption
      ptr -> operator[](1)  -= 5;   // crochetage
      ptr -> operator[](2)  += 5;   // mouvement silencieux
      ptr -> operator[](3)  += 5;   // détection des bruits
      ptr -> operator[](4)  += 10;  // détection de la magie
      ptr -> operator[](9)  -= 10;  // creuser des tunnels
      ptr -> operator[](10) += 10;  // se cacher dans l'ombre
      ptr -> operator[](12) += 5;   // vol à la tire
    }
  else if (race == "Gnome")
    {
      ptr -> operator[](0)  += 5;   // corruption
      ptr -> operator[](1)  += 5;   // crochetage
      ptr -> operator[](2)  += 5;   // mouvement silencieux
      ptr -> operator[](3)  += 10;  // détection des bruits
      ptr -> operator[](4)  += 5;   // détection de la magie
      ptr -> operator[](5)  += 10;  // détection des illusions
      ptr -> operator[](7)  -= 15;  // escalade
      ptr -> operator[](9)  += 5;   // creuser des tunnels
      ptr -> operator[](10) += 5;   // se cacher dans l'ombre
      ptr -> operator[](11) += 10;  // trouver et désamorcer les pièges
    }
  else if (race == "Demi-Elfe")
    {
      ptr -> operator[](0)  += 5;   // corruption
      ptr -> operator[](4)  += 5;   // détection de la magie
      ptr -> operator[](5)  += 5;   // détection des illusions
      ptr -> operator[](9)  -= 5;   // creuser des tunnels
      ptr -> operator[](10) += 5;   // se cacher dans l'ombre
      ptr -> operator[](12) += 10;  // vol à la tire
    }
  else if (race == "Demi-Orque")
    {
      ptr -> operator[](0)  += 10;  // corruption
      ptr -> operator[](3)  += 5;   // détection des bruits
      ptr -> operator[](5)  -= 5;   // détection des illusions
      ptr -> operator[](11) += 5;   // trouver et désamorcer les pièges
    }
  else if (race == "Hobbit")
    {
      ptr -> operator[](1)  += 5;   // crochetage
      ptr -> operator[](2)  += 10;  // mouvement silencieux
      ptr -> operator[](3)  += 5;   // détection des bruits
      ptr -> operator[](4)  += 5;   // détection de la magie
      ptr -> operator[](6)  += 10;  // évasion
      ptr -> operator[](7)  -= 15;  // escalade
      ptr -> operator[](8)  -= 5;   // lire des langues inconnues
      ptr -> operator[](9)  += 5;   // creuser des tunnels
      ptr -> operator[](10) += 15;  // se cacher dans l'ombre
      ptr -> operator[](11) += 5;   // trouver et désamorcer les pièges
      ptr -> operator[](12) += 5;   // vol à la tire
    }

  switch( dext )
    {
    case 9:
      ptr -> operator[](1)  -= 10;  // crochetage
      ptr -> operator[](2)  -= 20;  // mouvement silencieux
      ptr -> operator[](6)  -= 15;  // évasion
      ptr -> operator[](7)  -= 10;  // escalade
      ptr -> operator[](9) -= 10;  // creuser des tunnels
      ptr -> operator[](10) -= 10;  // se cacher dans l'ombre
      ptr -> operator[](11) -= 10;  // trouver et désamorcer les pièges
      ptr -> operator[](12) -= 15;  // vol à la tire
      break;
    case 10:
      ptr -> operator[](1)  -= 5;   // crochetage
      ptr -> operator[](2)  -= 15;  // mouvement silencieux
      ptr -> operator[](6)  -= 10;  // évasion
      ptr -> operator[](7)  -= 5;   // escalade
      ptr -> operator[](9)  -= 5;   // creuser des tunnels
      ptr -> operator[](10) -= 5;   // se cacher dans l'ombre
      ptr -> operator[](11) -= 10;  // trouver et désamorcer les pièges
      ptr -> operator[](12) -= 10;  // vol à la tire
      break;
    case 11:
      ptr -> operator[](2)  -= 10;  // mouvement silencieux
      ptr -> operator[](6)  -= 5;   // évasion
      ptr -> operator[](11) -= 5;   // trouver et désamorcer les pièges
      ptr -> operator[](12) -= 5;   // vol à la tire
      break;
    case 12:
      ptr -> operator[](2)  -= 5;   // mouvement silencieux
      break;
    case 16:
      ptr -> operator[](1)  += 5;   // crochetage
      break;
    case 17:
      ptr -> operator[](1)  += 10;  // crochetage
      ptr -> operator[](2)  += 5;   // mouvement silencieux
      ptr -> operator[](6)  += 5;   // évasion
      ptr -> operator[](7)  += 5;   // escalade
      ptr -> operator[](10) += 5;   // se cacher dans l'ombre
      ptr -> operator[](12) += 5;   // vol à la tire
      break;
    case 18:
      ptr -> operator[](1)  += 15;  // crochetage
      ptr -> operator[](2)  += 10;  // mouvement silencieux
      ptr -> operator[](6)  += 10;  // évasion
      ptr -> operator[](7)  += 10;  // escalade
      ptr -> operator[](9)  += 5;   // creuser des tunnels
      ptr -> operator[](10) += 10;  // se cacher dans l'ombre
      ptr -> operator[](11) += 5;   // trouver et désamorcer les pièges
      ptr -> operator[](12) += 10;  // vol à la tire
      break;
    case 19:
      ptr -> operator[](1)  += 20;  // crochetage
      ptr -> operator[](2)  += 15;  // mouvement silencieux
      ptr -> operator[](6)  += 15;  // évasion
      ptr -> operator[](7)  += 15;  // escalade
      ptr -> operator[](9)  += 10;  // creuser des tunnels
      ptr -> operator[](10) += 15;  // se cacher dans l'ombre
      ptr -> operator[](11) += 10;  // trouver et désamorcer les pièges
      ptr -> operator[](12) += 15;  // vol à la tire
      break;
    case 20:
      ptr -> operator[](1)  += 20;  // crochetage
      ptr -> operator[](2)  += 15;  // mouvement silencieux
      ptr -> operator[](6)  += 20;  // évasion
      ptr -> operator[](7)  += 20;  // escalade
      ptr -> operator[](9)  += 15;  // creuser des tunnels
      ptr -> operator[](10) += 20;  // se cacher dans l'ombre
      ptr -> operator[](11) += 15;  // trouver et désamorcer les pièges
      ptr -> operator[](12) += 20;  // vol à la tire
      break;
    case 21:
      ptr -> operator[](1)  += 25;  // crochetage
      ptr -> operator[](2)  += 20;  // mouvement silencieux
      ptr -> operator[](6)  += 25;  // évasion
      ptr -> operator[](7)  += 20;  // escalade
      ptr -> operator[](9)  += 20;  // creuser des tunnels
      ptr -> operator[](10) += 25;  // se cacher dans l'ombre
      ptr -> operator[](11) += 20;  // trouver et désamorcer les pièges
      ptr -> operator[](12) += 20;  // vol à la tire
      break;
    case 22:
      ptr -> operator[](1)  += 25;  // crochetage
      ptr -> operator[](2)  += 20;  // mouvement silencieux
      ptr -> operator[](6)  += 30;  // évasion
      ptr -> operator[](7)  += 25;  // escalade
      ptr -> operator[](9)  += 30;  // creuser des tunnels
      ptr -> operator[](10) += 30;  // se cacher dans l'ombre
      ptr -> operator[](11) += 20;  // trouver et désamorcer les pièges
      ptr -> operator[](12) += 25;  // vol à la tire
      break;
    }

  func() << "determinerScoresAjustes -> fin" << endreq;
  Debug::depileNiveau();
}

/**
 * Permet d'obtenir les scores "moyens" des talents de voleur, en
 * fonction du niveau. Ces nombres sont tirés de la table 19 du Guide
 * du Maître.
 *
 * Pour les compétences qui n'apparaissent pas dans la table 19, j'ai
 * choisi une valeur de base en me basant sur le nombre de points
 * qu'un Voleur peut dépenser. Ensuite j'ai appliqué une progression
 * toute simple et régulière.
 *
 * @param niveau niveau du PJ (dans la Classe considérée).
 * @param ptr pointeur sur le conteneur des scores, est modifié ici.
 */
void obtenirScoresBase(const unsigned int& niveau, vector<unsigned int>*& ptr)
{
  Debug::empileNiveau();
  func() << "obtenirScoresBase -> début" << endreq;

  ptr -> assign(13, 0);

  switch( niveau )
    {
    case 1:
      // 30 que je dois répartir
      ptr -> at(0)  = 15;  // corruption - base 5
      ptr -> at(1)  = 25;  // crochetage
      ptr -> at(2)  = 15;  // mouvement silencieux
      ptr -> at(3)  = 10;  // détection des bruits
      ptr -> at(4)  = 10;  // détection de la magie - base 5
      ptr -> at(5)  = 15;  // détection des illusions - base 10
      ptr -> at(6)  = 15;  // évasion - base 10
      ptr -> at(7)  = 85;  // escalade
      ptr -> at(8)  =  0;  // lire des langues inconnues
      ptr -> at(9)  = 20;  // creuser des tunnels - base 15
      ptr -> at(10) = 10;  // se cacher dans l'ombre
      ptr -> at(11) = 20;  // trouver et désamorcer les pièges
      ptr -> at(12) = 30;  // vol à la tire
      break;
    case 2:
      ptr -> at(0)  = 20;  // corruption
      ptr -> at(1)  = 29;
      ptr -> at(2)  = 21;
      ptr -> at(3)  = 10;
      ptr -> at(4)  = 10;  // détection de la magie
      ptr -> at(5)  = 15;  // détection des illusions
      ptr -> at(6)  = 20;  // évasion
      ptr -> at(7)  = 86;
      ptr -> at(8)  =  0;
      ptr -> at(9)  = 25;  // creuser des tunnels
      ptr -> at(10) = 15;
      ptr -> at(11) = 25;
      ptr -> at(12) = 35;
      break;
    case 3:
      ptr -> at(0)  = 25;  // corruption      
      ptr -> at(1)  = 33;
      ptr -> at(2)  = 27;
      ptr -> at(3)  = 15;
      ptr -> at(4)  = 15;  // détection de la magie
      ptr -> at(5)  = 20;  // détection des illusions
      ptr -> at(6)  = 25;  // évasion
      ptr -> at(7)  = 87;
      ptr -> at(8)  =  0;
      ptr -> at(9)  = 30;  // creuser des tunnels
      ptr -> at(10) = 20;
      ptr -> at(11) = 30;
      ptr -> at(12) = 40;
      break;
    case 4:
      ptr -> at(0)  = 30;  // corruption   
      ptr -> at(1)  = 37;
      ptr -> at(2)  = 33;
      ptr -> at(3)  = 15;
      ptr -> at(4)  = 15;  // détection de la magie
      ptr -> at(5)  = 20;  // détection des illusions
      ptr -> at(6)  = 30;  // évasion
      ptr -> at(7)  = 88;
      ptr -> at(8)  = 20;
      ptr -> at(9)  = 35;  // creuser des tunnels
      ptr -> at(10) = 25;
      ptr -> at(11) = 35;
      ptr -> at(12) = 45;
      break;
    case 5:
      ptr -> at(0)  = 35;  // corruption 
      ptr -> at(1)  = 42;
      ptr -> at(2)  = 40;
      ptr -> at(3)  = 20;
      ptr -> at(4)  = 20;  // détection de la magie
      ptr -> at(5)  = 25;  // détection des illusions
      ptr -> at(6)  = 35;  // évasion
      ptr -> at(7)  = 90;
      ptr -> at(8)  = 25;
      ptr -> at(9)  = 40;  // creuser des tunnels
      ptr -> at(10) = 31;
      ptr -> at(11) = 40;
      ptr -> at(12) = 50;
      break;
    case 6:
      ptr -> at(0)  = 40;  // corruption 
      ptr -> at(1)  = 47;
      ptr -> at(2)  = 47;
      ptr -> at(3)  = 20;
      ptr -> at(4)  = 20;  // détection de la magie
      ptr -> at(5)  = 25;  // détection des illusions
      ptr -> at(6)  = 40;  // évasion
      ptr -> at(7)  = 92;
      ptr -> at(8)  = 30;
      ptr -> at(9)  = 45;  // creuser des tunnels
      ptr -> at(10) = 37;
      ptr -> at(11) = 45;
      ptr -> at(12) = 55;
      break;
    case 7:
      ptr -> at(0)  = 45;  // corruption 
      ptr -> at(1)  = 52;
      ptr -> at(2)  = 55;
      ptr -> at(3)  = 25;
      ptr -> at(4)  = 25;  // détection de la magie
      ptr -> at(5)  = 30;  // détection des illusions
      ptr -> at(6)  = 45;  // évasion
      ptr -> at(7)  = 94;
      ptr -> at(8)  = 35;
      ptr -> at(9)  = 50;  // creuser des tunnels
      ptr -> at(10) = 43;
      ptr -> at(11) = 50;
      ptr -> at(12) = 60;
      break;
    case 8:
      ptr -> at(0)  = 45;  // corruption 
      ptr -> at(1)  = 57;
      ptr -> at(2)  = 62;
      ptr -> at(3)  = 25;
      ptr -> at(4)  = 25;  // détection de la magie
      ptr -> at(5)  = 30;  // détection des illusions
      ptr -> at(6)  = 55;  // évasion
      ptr -> at(7)  = 96;
      ptr -> at(8)  = 40;
      ptr -> at(9)  = 55;  // creuser des tunnels
      ptr -> at(10) = 49;
      ptr -> at(11) = 55;
      ptr -> at(12) = 65;
      break;
    case 9:
      ptr -> at(0)  = 45;  // corruption 
      ptr -> at(1)  = 62;
      ptr -> at(2)  = 70;
      ptr -> at(3)  = 30;
      ptr -> at(4)  = 30;  // détection de la magie
      ptr -> at(5)  = 35;  // détection des illusions
      ptr -> at(6)  = 60;  // évasion
      ptr -> at(7)  = 98;
      ptr -> at(8)  = 45;
      ptr -> at(9)  = 60;  // creuser des tunnels
      ptr -> at(10) = 56;
      ptr -> at(11) = 60;
      ptr -> at(12) = 70;
      break;
    case 10:
      ptr -> at(0)  = 50;  // corruption
      ptr -> at(1)  = 67;
      ptr -> at(2)  = 78;
      ptr -> at(3)  = 30;
      ptr -> at(4)  = 30;  // détection de la magie
      ptr -> at(5)  = 35;  // détection des illusions
      ptr -> at(6)  = 70;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 50;
      ptr -> at(9)  = 65;  // creuser des tunnels
      ptr -> at(10) = 63;
      ptr -> at(11) = 65;
      ptr -> at(12) = 80;
      break;
    case 11:
      ptr -> at(0)  = 55;  // corruption
      ptr -> at(1)  = 72;
      ptr -> at(2)  = 86;
      ptr -> at(3)  = 35;
      ptr -> at(4)  = 35;  // détection de la magie
      ptr -> at(5)  = 40;  // détection des illusions
      ptr -> at(6)  = 75;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 55;
      ptr -> at(9)  = 70;  // creuser des tunnels
      ptr -> at(10) = 70;
      ptr -> at(11) = 70;
      ptr -> at(12) = 90;
      break;
    case 12:
      ptr -> at(0)  = 60;  // corruption
      ptr -> at(1)  = 77;
      ptr -> at(2)  = 94;
      ptr -> at(3)  = 35;
      ptr -> at(4)  = 35;  // détection de la magie
      ptr -> at(5)  = 40;  // détection des illusions
      ptr -> at(6)  = 80;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 60;
      ptr -> at(9)  = 75;  // creuser des tunnels
      ptr -> at(10) = 77;
      ptr -> at(11) = 75;
      ptr -> at(12) = 95;
      break;
    case 13:
      ptr -> at(0)  = 65;  // corruption
      ptr -> at(1)  = 82;
      ptr -> at(2)  = 99;
      ptr -> at(3)  = 40;
      ptr -> at(4)  = 40;  // détection de la magie
      ptr -> at(5)  = 45;  // détection des illusions
      ptr -> at(6)  = 85;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 65;
      ptr -> at(9)  = 80;  // creuser des tunnels
      ptr -> at(10) = 85;
      ptr -> at(11) = 80;
      ptr -> at(12) = 99;
      break;
    case 14:
      ptr -> at(0)  = 65;  // corruption
      ptr -> at(1)  = 87;
      ptr -> at(2)  = 99;
      ptr -> at(3)  = 40;
      ptr -> at(4)  = 40;  // détection de la magie
      ptr -> at(5)  = 45;  // détection des illusions
      ptr -> at(6)  = 90;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 70;
      ptr -> at(9)  = 85;  // creuser des tunnels
      ptr -> at(10) = 93;
      ptr -> at(11) = 85;
      ptr -> at(12) = 99;
      break;
    case 15:
      ptr -> at(0)  = 70;  // corruption
      ptr -> at(1)  = 92;
      ptr -> at(2)  = 99;
      ptr -> at(3)  = 50;
      ptr -> at(4)  = 50;  // détection de la magie
      ptr -> at(5)  = 55;  // détection des illusions
      ptr -> at(6)  = 95;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 75;
      ptr -> at(9)  = 90;  // creuser des tunnels
      ptr -> at(10) = 99;
      ptr -> at(11) = 90;
      ptr -> at(12) = 99;
      break;
    case 16:
      ptr -> at(0)  = 75;  // corruption
      ptr -> at(1)  = 97;
      ptr -> at(2)  = 99;
      ptr -> at(3)  = 50;
      ptr -> at(4)  = 50;  // détection de la magie
      ptr -> at(5)  = 55;  // détection des illusions
      ptr -> at(6)  = 99;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 80;
      ptr -> at(9)  = 95;  // creuser des tunnels
      ptr -> at(10) = 99;
      ptr -> at(11) = 95;
      ptr -> at(12) = 99;
      break;
    default:
      ptr -> at(0)  = 80;  // corruption
      ptr -> at(1)  = 99;
      ptr -> at(2)  = 99;
      ptr -> at(3)  = 55;
      ptr -> at(4)  = 55;  // détection de la magie
      ptr -> at(5)  = 55;  // détection des illusions
      ptr -> at(6)  = 99;  // évasion
      ptr -> at(7)  = 99;
      ptr -> at(8)  = 80;
      ptr -> at(9)  = 99;  // creuser des tunnels
      ptr -> at(10) = 99;
      ptr -> at(11) = 99;
      ptr -> at(12) = 99;
    }

  func() << "obtenirScoresBase -> fin" << endreq;
  Debug::depileNiveau();
}



/*******************************************************************************
 ******************************************************************************/

/*******************************************************************************
 ******************************************************************************/
/** @} */
